package com.dc.web.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.dc.Application;
import com.dc.config.excel.EasyExcelUtil;
import com.dc.constant.MessageConstant;
import com.dc.dao.*;
import com.dc.entity.*;
import com.dc.exception.ServiceException;
import com.dc.service.CalibrationStatService;
import com.dc.service.dto.*;
import com.dc.utils.JSONUtils2;
import com.dc.utils.JsonUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

@Api(tags = "excel导出")
@RestController
@RequestMapping("/api/excel/export")
@Slf4j
public class ExportController {

    @Resource
    MaterialMachineDao materialMachineDao;

    @Resource
    MaterialSolidDao materialSolidDao;

    @Resource
    ShipRepairDao shipRepairDao;

    @Resource
    ShipDao shipDao;

    @Resource
    DepartmentDao departmentDao;

    @Resource
    CalibrationStatService calibrationStatService;

    @GetMapping("/machine")
    public void exportMachine(Long shipRepairId, Long departId, HttpServletRequest req, HttpServletResponse res) {

        Optional<ShipRepairEntity> optionalShipRepair = shipRepairDao.findById(shipRepairId);
        if (!optionalShipRepair.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_REPAIR_MISSING);
        }
        ShipRepairEntity shipRepairEntity = optionalShipRepair.get();

        Optional<ShipEntity> optionalShip = shipDao.findById(shipRepairEntity.getShipId());
        if(!optionalShip.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
        }
        ShipEntity shipEntity = optionalShip.get();

        Optional<DepartmentEntity> optionalDepartment = departmentDao.findById(departId);
        if (!optionalDepartment.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_DEPARTMENT_MISSING);
        }
        DepartmentEntity departmentEntity = optionalDepartment.get();

        List<MaterialMachineEntity> list = materialMachineDao.findByShipRepairEntityAndDepartment(shipRepairEntity, departmentEntity);


        try {
            String fileName = URLEncoder.encode(shipEntity.getName() + "物量设备", "UTF-8").replaceAll("\\+", "%20");

            res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setCharacterEncoding("utf-8");
            res.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            List<Map<String, Object>> mapList = new ArrayList<>();
            int index = 0;
            for(MaterialMachineEntity materialMachineEntity : list) {
                index++;
                Map<String, Object> map = new HashMap<>();
                map.put("index", index);
                map.put("supplierUnit", materialMachineEntity.getSupplierUnit());
                map.put("machine", materialMachineEntity.getMachine());
                map.put("machineCode", materialMachineEntity.getMachineCode());
                map.put("num", materialMachineEntity.getNum());
                map.put("unit", materialMachineEntity.getUnit());
                map.put("hours", materialMachineEntity.getHours());

                mapList.add(map);
            }

            //这里需要注册自己定义的处理器CustomSheetWriteHandler，CustomRowWriteHandler，否则不起作用
            ApplicationHome h = new ApplicationHome(Application.class);
            File dir = h.getDir();
            String realPath = dir + File.separator + "template" + File.separator + "物量设备模版.xlsx";

            System.out.println(realPath);

            EasyExcel.write(res.getOutputStream(), Map.class)
                    .withTemplate(realPath)
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet(0).doFill(mapList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/solid")
    public void exportSolid(Long shipRepairId, Long departId, HttpServletRequest req, HttpServletResponse res) {

        Optional<ShipRepairEntity> optionalShipRepair = shipRepairDao.findById(shipRepairId);
        if (!optionalShipRepair.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_REPAIR_MISSING);
        }
        ShipRepairEntity shipRepairEntity = optionalShipRepair.get();

        Optional<ShipEntity> optionalShip = shipDao.findById(shipRepairEntity.getShipId());
        if(!optionalShip.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
        }
        ShipEntity shipEntity = optionalShip.get();

        Optional<DepartmentEntity> optionalDepartment = departmentDao.findById(departId);
        if (!optionalDepartment.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_DEPARTMENT_MISSING);
        }
        DepartmentEntity departmentEntity = optionalDepartment.get();

        List<MaterialSolidEntity> list = materialSolidDao.findByShipRepairEntityAndDepartment(shipRepairEntity, departmentEntity);


        try {
            String fileName = URLEncoder.encode(shipEntity.getName() + "物量材料", "UTF-8").replaceAll("\\+", "%20");

            res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setCharacterEncoding("utf-8");
            res.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            List<Map<String, Object>> mapList = new ArrayList<>();
            int index = 0;
            for(MaterialSolidEntity materialSolidEntity : list) {
                index++;
                Map<String, Object> map = new HashMap<>();
                map.put("index", index);
                map.put("supplierUnit", materialSolidEntity.getSupplierUnit());
                map.put("pickingDepart", materialSolidEntity.getPickingDepart());
                map.put("transactionType", materialSolidEntity.getTransactionType());
                map.put("projectCode", materialSolidEntity.getProjectCode());
                map.put("projectName", materialSolidEntity.getProjectName());
                map.put("materialCode", materialSolidEntity.getMaterialCode());
                map.put("materialName", materialSolidEntity.getMaterialName());
                map.put("materialGroup", materialSolidEntity.getMaterialGroup());
                map.put("shippedNum", materialSolidEntity.getShippedNum());
                map.put("unit", materialSolidEntity.getUnit());
                map.put("unitWeight", materialSolidEntity.getUnitWeight());
                map.put("totalWeight", materialSolidEntity.getTotalWeight());
                map.put("buyingCom", materialSolidEntity.getBuyingCom());
                map.put("supplierCom", materialSolidEntity.getSupplierCom());

                mapList.add(map);
            }

            //这里需要注册自己定义的处理器CustomSheetWriteHandler，CustomRowWriteHandler，否则不起作用
            ApplicationHome h = new ApplicationHome(Application.class);
            File dir = h.getDir();
            String realPath = dir + File.separator + "template" + File.separator + "material-solid.xlsx";

            System.out.println(realPath);

            EasyExcel.write(res.getOutputStream(), Map.class)
                    .withTemplate(realPath)
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet(0).doFill(mapList);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    // 标定
    @ApiOperation("船体下料 二级")
    @GetMapping("/calibration/stat/ship_cut/second")
    public void exportCalibrationShipCutSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.shipCutSecond();

        try {
            String fileName = URLEncoder.encode("标定-船体下料-二级", "UTF-8").replaceAll("\\+", "%20");

            res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setCharacterEncoding("utf-8");
            res.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            //这里需要注册自己定义的处理器CustomSheetWriteHandler，CustomRowWriteHandler，否则不起作用
            ApplicationHome h = new ApplicationHome(Application.class);
            File dir = h.getDir();
            String realPath = dir + File.separator + "template" + File.separator + "标定-船体下料-2.xlsx";

            System.out.println(realPath);

            ExcelWriter excelWriter = EasyExcel.write(res.getOutputStream())
                    .withTemplate(realPath)
                    .excelType(ExcelTypeEnum.XLSX).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            excelWriter.fill(dataMap.get(CalibrationStatService.DATA), writeSheet);
            // 写入list之前的数据
            CalibrationShipCutDto o = (CalibrationShipCutDto)dataMap.get(CalibrationStatService.STAT);

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("unitAirPower", o.getUnitAirPower());
            map.put("powerUnit", o.getPowerUnit());
            map.put("o2Unit", o.getO2Unit());
            map.put("airUnit", o.getAirUnit());
            map.put("powerAirUnit", o.getPowerAirUnit());

            excelWriter.fill(map, writeSheet);

            excelWriter.finish();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("船体下料 三级")
    @GetMapping("/calibration/stat/ship_cut/third")
    public void exportCalibrationShipCutThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.shipCutThird();

        try {
            String fileName = URLEncoder.encode("标定-船体下料-三级", "UTF-8").replaceAll("\\+", "%20");

            res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setCharacterEncoding("utf-8");
            res.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            //这里需要注册自己定义的处理器CustomSheetWriteHandler，CustomRowWriteHandler，否则不起作用
            ApplicationHome h = new ApplicationHome(Application.class);
            File dir = h.getDir();
            String realPath = dir + File.separator + "template" + File.separator + "标定-船体下料-3.xlsx";

            System.out.println(realPath);

            ExcelWriter excelWriter = EasyExcel.write(res.getOutputStream())
                    .withTemplate(realPath)
                    .excelType(ExcelTypeEnum.XLSX).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            excelWriter.fill(dataMap.get(CalibrationStatService.DATA), writeSheet);

            excelWriter.finish();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("船体割旧 二级")
    @GetMapping("/calibration/stat/ship_old/second")
    public void exportCalibrationShipOldSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.shipOldSecond();
        second(dataMap, "标定-船体割旧-二级", "标定-船体割旧-2.xlsx", res);
    }

    @ApiOperation("船体割旧 三级")
    @GetMapping("/calibration/stat/ship_old/third")
    public void exportCalibrationShipOldThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.shipOldThird();

        third(dataMap, "标定-船体割旧-三级", "标定-船体割旧-3.xlsx", res);
    }

    @ApiOperation("船体焊接 二级")
    @GetMapping("/calibration/stat/ship_weld/second")
    public void exportCalibrationShipWeldSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.shipWeldSecond();
        second(dataMap, "标定-船体焊接-二级", "标定-船体焊接-2.xlsx", res);
    }

    // 船体焊接-三级
    @ApiOperation("船体焊接 三级")
    @GetMapping("/calibration/stat/ship_weld/third")
    public void exportCalibrationShipWeldThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.shipWeldThird();
        List<CalibrationShipWeldEntity> list = (List<CalibrationShipWeldEntity>)dataMap.get(CalibrationStatService.DATA);
        List<CalibrationShipWeldExcelDto> result = new ArrayList<>();
        for(CalibrationShipWeldEntity entity : list) {
            List<CalibrationShipWeldChildEntity> inner = entity.getInner();

            CalibrationShipWeldExcelDto dto = new CalibrationShipWeldExcelDto();
            BeanUtils.copyProperties(entity, dto);
            result.add(dto);

            if(Objects.isNull(inner)) {
                continue;
            }

            boolean flag = true;
            for(CalibrationShipWeldChildEntity innerEntity : inner) {

                if(flag) {
                    BeanUtils.copyProperties(innerEntity, dto);
                    flag = false;
                } else {
                    CalibrationShipWeldExcelDto dto2 = new CalibrationShipWeldExcelDto();
                    BeanUtils.copyProperties(innerEntity, dto2);
                    result.add(dto2);
                }
            }
        }

        thirdFatherSon(result, "标定-船体焊接-三级", "标定-船体焊接-3.xlsx", res);
    }



    ////   超水除锈还未处理

    @ApiOperation("法兰管子焊接 二级")
    @GetMapping("/calibration/stat/machine_pipe/fa/second")
    public void exportMachinePipeFaSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.machinePipeSecond("法兰", null);
        second(dataMap, "标定-法兰管子焊接-二级", "标定-法兰管子焊接-2.xlsx", res);
    }

    @ApiOperation("弯头管子焊接 二级")
    @GetMapping("/calibration/stat/machine_pipe/wan/second")
    public void exportMachinePipeWanSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.machinePipeSecond("弯头", null);
        second(dataMap, "标定-弯头管子焊接-二级", "标定-弯头管子焊接-2.xlsx", res);
    }

    @ApiOperation("喷漆房分段喷漆 二级")
    @GetMapping("/calibration/stat/paint_house/second")
    public void exportPaintHouseSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.paintHouseSecond();
        second(dataMap, "标定-喷漆房分段喷漆-二级", "标定-喷漆房分段喷漆-2.xlsx", res);
    }

    /////  喷漆房分段喷漆-三级
    @ApiOperation("喷漆房分段喷漆 三级")
    @GetMapping("/calibration/stat/paint_house/third")
    public void exportPaintHouseThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.paintHouseThird();
        List<CalibrationPaintHouseEntity> list = (List<CalibrationPaintHouseEntity>)dataMap.get(CalibrationStatService.DATA);
        List<CalibrationPaintHouseExcelDto> result = new ArrayList<>();
        for(CalibrationPaintHouseEntity entity : list) {
            List<CalibrationPaintHouseChildEntity> inner = entity.getInner();

            CalibrationPaintHouseExcelDto dto = new CalibrationPaintHouseExcelDto();
            BeanUtils.copyProperties(entity, dto);
            result.add(dto);

            if(Objects.isNull(inner)) {
                continue;
            }

            boolean flag = true;
            for(CalibrationPaintHouseChildEntity innerEntity : inner) {
                if(flag) {
                    BeanUtils.copyProperties(innerEntity, dto);
                    flag = false;
                } else {
                    CalibrationPaintHouseExcelDto dto2 = new CalibrationPaintHouseExcelDto();
                    BeanUtils.copyProperties(innerEntity, dto2);
                    result.add(dto2);
                }
            }
        }

        thirdFatherSon(result, "标定-喷漆房分段喷漆-三级", "标定-喷漆房分段喷漆-3.xlsx", res);
    }

    @ApiOperation("舱室及船壳喷漆 二级")
    @GetMapping("/calibration/stat/paint_ship/second")
    public void exportPaintShipSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.paintShipSecond();
        second(dataMap, "标定-舱室及船壳喷漆-二级", "标定-舱室及船壳喷漆-2.xlsx", res);
    }

    @ApiOperation("舱室及船壳喷漆 三级")
    @GetMapping("/calibration/stat/paint_ship/third")
    public void exportPaintShipThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.paintShipThird();
        third(dataMap, "标定-舱室及船壳喷漆-三级", "标定-舱室及船壳喷漆-3.xlsx", res);
    }

    @ApiOperation("打砂房分段打砂 二级")
    @GetMapping("/calibration/stat/sand_house/second")
    public void exportSandHouseSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.sandHouseSecond();
        second(dataMap, "标定-打砂房分段打砂-二级", "标定-打砂房分段打砂-2.xlsx", res);
    }

    @ApiOperation("打砂房分段打砂 三级")
    @GetMapping("/calibration/stat/sand_house/third")
    public void exportSandHouseThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.sandHouseThird();
        List<CalibrationHouseSandEntity> list = (List<CalibrationHouseSandEntity>)dataMap.get(CalibrationStatService.DATA);
        List<CalibrationHouseSandExcelDto> result = new ArrayList<>();
        for(CalibrationHouseSandEntity entity : list) {
            List<CalibrationHouseSandChildEntity> inner = entity.getInner();


            CalibrationHouseSandExcelDto dto = new CalibrationHouseSandExcelDto();
            BeanUtils.copyProperties(entity, dto);
            dto.setPowers(entity.getPower());
            result.add(dto);

            if(Objects.isNull(inner)) {
                continue;
            }

            boolean flag = true;
            for(CalibrationHouseSandChildEntity innerEntity : inner) {

                if(flag) {
                    BeanUtils.copyProperties(innerEntity, dto);
                    dto.setPowers(entity.getPower());
                    flag = false;
                } else {
                    CalibrationHouseSandExcelDto dto2 = new CalibrationHouseSandExcelDto();
                    BeanUtils.copyProperties(innerEntity, dto2); // 两次 copy 不可交换顺序，因为power重复
                    result.add(dto2);
                }
            }
        }

        thirdFatherSon(result, "标定-打砂房分段打砂-三级", "标定-打砂房分段打砂-3.xlsx", res);
    }

    @ApiOperation("舱室打砂 二级")
    @GetMapping("/calibration/stat/sand_ship/second")
    public void exportSandShipSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.sandShipSecond();
        second(dataMap, "标定-舱室打砂-二级", "标定-舱室打砂-2.xlsx", res);
    }

    @ApiOperation("舱室打砂 三级")
    @GetMapping("/calibration/stat/sand_ship/third")
    public void exportSandShipThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.sandShipThird();
        third(dataMap, "标定-舱室打砂-三级", "标定-舱室打砂-3.xlsx", res);
    }


    @ApiOperation("超水清洁点打 二级")
    @GetMapping("/calibration/stat/water_clean_point/second")
    public void exportWaterCleanPointSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanPointSecond();
        second(dataMap, "标定-超水清洁点打-二级", "标定-超水清洁点打-2.xlsx", res);
    }

    @ApiOperation("超水清洁点打 三级")
    @GetMapping("/calibration/stat/water_clean_point/third")
    public void exportWaterCleanPointThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanPointThird();

        List<CalibrationWaterCleanPointEntity> list = (List<CalibrationWaterCleanPointEntity>)dataMap.get(CalibrationStatService.DATA);
        List<CalibrationWaterCleanPointExcelDto> result = new ArrayList<>();
        for(CalibrationWaterCleanPointEntity entity : list) {
            List<CalibrationWaterCleanPointChildEntity> inner = entity.getInner();

            CalibrationWaterCleanPointExcelDto dto = new CalibrationWaterCleanPointExcelDto();
            BeanUtils.copyProperties(entity, dto);
            dto.setPowers(entity.getPower());
            result.add(dto);

            if(Objects.isNull(inner)) {
                continue;
            }

            boolean flag = true;
            for(CalibrationWaterCleanPointChildEntity innerEntity : inner) {

                if(flag) {
                    BeanUtils.copyProperties(innerEntity, dto);
                    dto.setPowers(entity.getPower());
                    flag = false;
                } else {
                    CalibrationWaterCleanPointExcelDto dto2 = new CalibrationWaterCleanPointExcelDto();
                    BeanUtils.copyProperties(innerEntity, dto2); // 两次 copy 不可交换顺序，因为power重复
                    result.add(dto2);
                }
            }
        }
        thirdFatherSon(result, "标定-超水清洁点打-三级", "标定-超水清洁点打-3.xlsx", res);
    }

    @ApiOperation("超水清洁 二级")
    @GetMapping("/calibration/stat/water_clean/second")
    public void exportWaterCleanSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanSecond();
        second(dataMap, "标定-超水清洁-二级", "标定-超水清洁-2.xlsx", res);
    }

    @ApiOperation("超水清洁 三级")
    @GetMapping("/calibration/stat/water_clean/third")
    public void exportWaterCleanThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanThird();

        List<CalibrationWaterCleanEntity> list = (List<CalibrationWaterCleanEntity>)dataMap.get(CalibrationStatService.DATA);
        List<CalibrationWaterCleanExcelDto> result = new ArrayList<>();
        for(CalibrationWaterCleanEntity entity : list) {
            List<CalibrationWaterCleanChildEntity> inner = entity.getInner();

            CalibrationWaterCleanExcelDto dto = new CalibrationWaterCleanExcelDto();
            BeanUtils.copyProperties(entity, dto);
            result.add(dto);

            if(Objects.isNull(inner)) {
                continue;
            }

            boolean flag = true;
            for(CalibrationWaterCleanChildEntity innerEntity : inner) {

                if(flag) {
                    BeanUtils.copyProperties(innerEntity, dto);
                    flag = false;
                } else {
                    CalibrationWaterCleanExcelDto dto2 = new CalibrationWaterCleanExcelDto();
                    BeanUtils.copyProperties(innerEntity, dto2); // 两次 copy 不可交换顺序，因为power重复
                    result.add(dto2);
                }
            }
        }
        thirdFatherSon(result, "标定-超水清洁-三级", "标定-超水清洁-3.xlsx", res);
    }

    @ApiOperation("超水除锈 二级")
    @GetMapping("/calibration/stat/water_clean_rust/second")
    public void exportWaterCleanRustSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanRustSecond();
        second(dataMap, "标定-超水除锈-二级", "标定-超水除锈-2.xlsx", res);
    }

    @ApiOperation("超水除锈 三级")
    @GetMapping("/calibration/stat/water_clean_rust/third")
    public void exportWaterCleanRustThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanRustThird();

        List<CalibrationWaterRustCleanEntity> list = (List<CalibrationWaterRustCleanEntity>)dataMap.get(CalibrationStatService.DATA);
        List<CalibrationWaterRustCleanExcelDto> result = new ArrayList<>();
        for(CalibrationWaterRustCleanEntity entity : list) {
            List<CalibrationWaterRustCleanChildEntity> inner = entity.getInner();

            CalibrationWaterRustCleanExcelDto dto = new CalibrationWaterRustCleanExcelDto();
            BeanUtils.copyProperties(entity, dto);
            result.add(dto);

            if(Objects.isNull(inner)) {
                continue;
            }

            boolean flag = true;
            for(CalibrationWaterRustCleanChildEntity innerEntity : inner) {

                if(flag) {
                    BeanUtils.copyProperties(innerEntity, dto);
                    flag = false;
                } else {
                    CalibrationWaterRustCleanExcelDto dto2 = new CalibrationWaterRustCleanExcelDto();
                    BeanUtils.copyProperties(innerEntity, dto2); // 两次 copy 不可交换顺序，因为power重复
                    result.add(dto2);
                }
            }
        }

        thirdFatherSon(result, "标定-超水除锈-三级", "标定-超水除锈-3.xlsx", res);
    }

    @ApiOperation("舱盖超水除锈 二级")
    @GetMapping("/calibration/stat/water_clean_rust_ship/second")
    public void exportWaterCleanRustShipSecond(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanRustShipSecond();
        second(dataMap, "标定-舱盖超水除锈-二级", "标定-舱盖超水除锈-2.xlsx", res);
    }

    @ApiOperation("舱盖超水除锈 三级")
    @GetMapping("/calibration/stat/water_clean_rust_ship/third")
    public void exportWaterCleanRustShipThird(HttpServletResponse res) {
        Map<String, Object> dataMap = calibrationStatService.waterCleanRustShipThird();

        List<CalibrationWaterCleanRustShipEntity> list = (List<CalibrationWaterCleanRustShipEntity>)dataMap.get(CalibrationStatService.DATA);
        List<CalibrationWaterCleanRustShipExcelDto> result = new ArrayList<>();
        for(CalibrationWaterCleanRustShipEntity entity : list) {
            List<CalibrationWaterCleanRustShipChildEntity> inner = entity.getInner();

            CalibrationWaterCleanRustShipExcelDto dto = new CalibrationWaterCleanRustShipExcelDto();
            BeanUtils.copyProperties(entity, dto);
            result.add(dto);

            if(Objects.isNull(inner)) {
                continue;
            }

            boolean flag = true;
            for(CalibrationWaterCleanRustShipChildEntity innerEntity : inner) {

                if(flag) {
                    BeanUtils.copyProperties(innerEntity, dto);
                    flag = false;
                } else {
                    CalibrationWaterCleanRustShipExcelDto dto2 = new CalibrationWaterCleanRustShipExcelDto();
                    BeanUtils.copyProperties(innerEntity, dto2); // 两次 copy 不可交换顺序，因为power重复
                    result.add(dto2);
                }
            }
        }

        thirdFatherSon(result, "标定-舱盖超水除锈-三级", "标定-舱盖超水除锈-3.xlsx", res);
    }


    private void second(Map<String, Object> dataMap, String resFileName, String templateFileName, HttpServletResponse res) {
        try {
            String fileName = URLEncoder.encode(resFileName, "UTF-8").replaceAll("\\+", "%20");

            res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setCharacterEncoding("utf-8");
            res.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            //这里需要注册自己定义的处理器CustomSheetWriteHandler，CustomRowWriteHandler，否则不起作用
            ApplicationHome h = new ApplicationHome(Application.class);
            File dir = h.getDir();
            String realPath = dir + File.separator + "template" + File.separator + templateFileName;

            System.out.println(realPath);

            ExcelWriter excelWriter = EasyExcel.write(res.getOutputStream())
                    .withTemplate(realPath)
                    .excelType(ExcelTypeEnum.XLSX).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            excelWriter.fill(dataMap.get(CalibrationStatService.DATA), writeSheet);
            // 写入list之前的数据
//            CalibrationShipOldDto o = (CalibrationShipOldDto)dataMap.get(CalibrationStatService.STAT);

//            Map<String, Object> map = new HashMap<String, Object>();
//            map.put("gasByUnit", o.getGasByUnit());
//            map.put("o2ByUnit", o.getO2ByUnit());
            Map<String, Object> map = JSONUtils2.obj2Map(dataMap.get(CalibrationStatService.STAT));

            excelWriter.fill(map, writeSheet);

            excelWriter.finish();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void third(Map<String, Object> dataMap, String resFileName, String templateFileName, HttpServletResponse res) {
        try {
            String fileName = URLEncoder.encode(resFileName, "UTF-8").replaceAll("\\+", "%20");

            res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setCharacterEncoding("utf-8");
            res.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            //这里需要注册自己定义的处理器CustomSheetWriteHandler，CustomRowWriteHandler，否则不起作用
            ApplicationHome h = new ApplicationHome(Application.class);
            File dir = h.getDir();
            String realPath = dir + File.separator + "template" + File.separator + templateFileName;

            System.out.println(realPath);

            ExcelWriter excelWriter = EasyExcel.write(res.getOutputStream())
                    .withTemplate(realPath)
                    .excelType(ExcelTypeEnum.XLSX).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            excelWriter.fill(dataMap.get(CalibrationStatService.DATA), writeSheet);

            excelWriter.finish();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void thirdFatherSon(List list, String resFileName, String templateFileName, HttpServletResponse res) {
        try {
            String fileName = URLEncoder.encode(resFileName, "UTF-8").replaceAll("\\+", "%20");

            res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setCharacterEncoding("utf-8");
            res.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            //这里需要注册自己定义的处理器CustomSheetWriteHandler，CustomRowWriteHandler，否则不起作用
            ApplicationHome h = new ApplicationHome(Application.class);
            File dir = h.getDir();
            String realPath = dir + File.separator + "template" + File.separator + templateFileName;

            System.out.println(realPath);

            ExcelWriter excelWriter = EasyExcel.write(res.getOutputStream())
                    .withTemplate(realPath)
                    .excelType(ExcelTypeEnum.XLSX).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();

            //子母数据处理
            excelWriter.fill(list, writeSheet);

            excelWriter.finish();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
